package com.qiwx.pigeon.data.network;

import android.content.Context;
import android.text.TextUtils;

import com.facebook.common.internal.Throwables;
import com.google.gson.JsonSyntaxException;
import com.qiwx.pigeon.BuildConfig;
import com.qiwx.pigeon.R;
import com.qiwx.pigeon.app.AppContext;
import com.qiwx.pigeon.base.IBaseView;

import java.io.IOException;
import java.net.SocketTimeoutException;

import retrofit2.adapter.rxjava.HttpException;
import rx.Subscriber;

/**
 * Created by JZG on 2017/3/30.
 */

public abstract class ResponseSubscriber<T extends ResponseJson> extends Subscriber<T> {
    protected boolean showLoading; //是否显示loadingDialog
    private String loadingText; //loadingDialog下发的文字
    private ResponseStatus[] mSuccessCodes;

    public ResponseSubscriber(ResponseStatus... successCodes) {
        this(false, successCodes);
    }

    public ResponseSubscriber(boolean showLoading, ResponseStatus... successCodes) {
        this(showLoading, null, successCodes);
    }

    public ResponseSubscriber(boolean showLoading, String loadingText, ResponseStatus... successCodes) {
        this.showLoading = showLoading;
        this.loadingText = loadingText;
        initSuccessCodes(successCodes);
    }

    private void initSuccessCodes(ResponseStatus[] successCodes) {
        if (successCodes != null && successCodes.length > 0) {
            mSuccessCodes = new ResponseStatus[successCodes.length + 1];
            mSuccessCodes[0] = ResponseStatus.OK;
            System.arraycopy(successCodes, 0, mSuccessCodes, 1, successCodes.length);
        } else {
            mSuccessCodes = new ResponseStatus[]{ResponseStatus.OK};
        }
    }

    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {
        e.printStackTrace();
        if (checkNullIView()) {
            return;
        }
        if (showLoading) {
            dismissLoading();
        }

        String error = null;
        if (e instanceof SocketTimeoutException) {
            error = "系统等待超时，请重试";
        } else if (e instanceof IOException) {
            error = "IOException";
        } else if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            error = httpException.getMessage();
        } else if (e instanceof JsonSyntaxException) {
            error = "数据校验失败，请稍后再试";
        } else if (e instanceof NullPointerException) {//NullPointerException 可能是服务器错误 导致 日志拦截器出错
            error = "数据加载失败，请稍后再试";
        } else {
            if (BuildConfig.DEBUG) {
                error = e.getMessage();
            }
            if (TextUtils.isEmpty(error)) {
                error = "未知错误";
            }
            //打印异常栈顶信息
            if (BuildConfig.DEBUG) {
                Throwables.propagate(new RuntimeException(error));
            }
        }
        onFailure(error);
        /**
         * {@link com.jzg.secondcar.dealer.base.BaseActivity#showError(String)}
         * {@link com.jzg.secondcar.dealer.utils.ToastUtil#show(Context, CharSequence, int)}
         * 放过去，主要是为了能够更新页面  但不toast
         */
        if ("no&&&Login".equals(error)) {
            error = "";
        } else {
            if (BuildConfig.DEBUG) {
                error = e.getMessage();
                if (TextUtils.isEmpty(error)) {
                    error = "未知错误";
                }
            }
        }
        try {
            if (!onInterceptShowError(e)) {
                showError(error);
            }
        } catch (Exception e1) {
            if (BuildConfig.DEBUG) {
                Throwables.propagate(e);
            }
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        if (checkNullIView()) {
            return;
        }
        if (showLoading) {
            if (!TextUtils.isEmpty(loadingText)) {
                showLoading(loadingText);
            } else {
                showLoading();
            }
        }
        if (!AppContext.isNetWork) {
            unsubscribe();
            //onError("没有网络");
        }
    }

    @Override
    public void onNext(T t) {
        if (checkNullIView()) {
            return;
        }
        int status = t.getStatus();
        boolean success = false;
        for (ResponseStatus successCode : mSuccessCodes) {
            if (successCode.getValue() == status) {
                success = true;
                break;
            }
        }
        if (success) {
            if (showLoading) {
                dismissLoading();
            }
            try {
                onSuccess(t);
            } catch (Exception e) {
                if (BuildConfig.DEBUG) {
                    Throwables.propagate(e);
                }
            }
        } else {
            String error = t.getMsg();
            if (BuildConfig.DEBUG) {
//                error = "[status: " + status + " ,  message: " + t.getMsg() + "]";
            }
            if (status == ResponseStatus.NO_LOGIN.getValue()) {//未登录  不能返回  不然UI 没法更新
                onNoLogin(t.getMsg());
                error = "no&&&Login";
            }
            if (status == ResponseStatus.SINGLE_LOGIN.getValue()) {//被踢了  不能返回  不然UI 没法更新
                onSingleLoginView(t.getMsg());
                error = "no&&&Login";
            }
            if (status == ResponseStatus.USER_DISABLE.getValue()) {//用户被禁止
                onUserDisable(t.getMsg());
                error = "no&&&Login";
            }else {
                onFailure(error);
                showError(error);
            }

           // throw new RuntimeException(error);
        }
    }

    public abstract IBaseView getIView();

    public abstract void onSuccess(T response);

    public void onFailure(String error) {

    }

    /**
     * 这个方法返回true  回掉onFailure
     * 返回false   回掉showError     默认返回false
     *
     * @param e
     * @return 使用{@link #onFailure2(String)}方法 必须返回true
     */
    public boolean onInterceptShowError(Throwable e) {
        return false;
    }

    private boolean checkNullIView() {
        return getIView() == null;
    }

    private void showLoading(String loadingText) {
        if (checkNullIView()) {
            return;
        }
        if (TextUtils.isEmpty(loadingText)) {
            getIView().showLoading();
        } else {
            getIView().showLoading(loadingText);
        }
    }

    private void showLoading() {
        if (checkNullIView()) {
            return;
        }
        getIView().showLoading(null);
    }

    private void dismissLoading() {
        if (checkNullIView()) {
            return;
        }
        getIView().dismissLoading();
    }

    private void onNoLogin(String msg) {
        if (checkNullIView()) {
            return;
        }
        getIView().onNoLogin(msg);
    }

    private void onUserDisable(String msg) {
        if (checkNullIView()) {
            return;
        }
        getIView().onUserDisable(msg);
    }

    private void onSingleLoginView(String msg) {
        if (checkNullIView()) {
            return;
        }
        getIView().onSingleLoginView(msg);
    }

    private void showError(String error) {
        if (checkNullIView()) {
            return;
        }
        getIView().showError(error);

    }
}
